package com.mark.basic.service.Impl;

import com.mark.basic.contsants.BaseConstants;
import com.mark.basic.dto.PhoneDto;
import com.mark.basic.service.IVerifyCodeService;
import com.mark.basic.util.AjaxResult;
import com.mark.basic.util.BusinessException;
import com.mark.basic.util.StrUtils;
import com.mark.basic.util.VerifyCodeUtils;
import com.mark.user.domain.User;
import com.mark.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Override
    public String getImgCode(String key) {
        // 先判断key是否为空
        if(!StringUtils.hasLength("key")){
            throw new BusinessException("请填写验证码");
        }
        // 获取验证码
        String code = VerifyCodeUtils.generateVerifyCode(4);
        // 将验证码的值放入redis
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        // 将验证码的值转换为图片
        // 使用base64编码并返回
        try {
            String a = VerifyCodeUtils.VerifyCode(108,38,code);
                return a;
        } catch (BusinessException e) {
            e.printStackTrace();
            throw new BusinessException("验证码创建失败");
        }
    }

    @Override
    public AjaxResult sendsmsCode(PhoneDto smsDto) {
        // 将多次使用的数据抽出来
        String phone = smsDto.getPhone();
        String imageCode = smsDto.getImageCode();
        String imageCodeKey = smsDto.getImageCodeKey();
        String type = smsDto.getType();
        if ("binder".equals(type)){
            // 1、校验验证码是否为空
            System.out.println(phone);
            if(StringUtils.isEmpty(phone)){
                throw new BusinessException("请输入手机号");
            }
            // 2、手机号是否被注册
            User user = userMapper.listByPhone(phone);
            if (user!=null){
                throw new BusinessException("该手机号已注册");
            }
            String businessKey = BaseConstants.VerifyConstants.BUSINESS_BINDER_PREFIX + phone;
            sendSmsCode(businessKey);
        }else {
            // 1、校验验证码是否为空
            System.out.println(phone+ "======" + imageCode +"========"+imageCodeKey);
            if(!(StringUtils.isEmpty(phone)
                    || StringUtils.hasLength(imageCode)
                    || StringUtils.hasLength(imageCodeKey))){
                throw new BusinessException("请输入验证码");
            }
            // 2、手机号是否被注册
            User user = userMapper.listByPhone(phone);
            if (user!=null){
                throw new BusinessException("该手机号已注册");
            }
            // 3、图形验证码的校验（第二次以后）
            // 3.1 根据imgCodeKey来获取验证码
            Object imageCodeValue = redisTemplate.opsForValue().get(imageCodeKey);
            // 3.1.1 如果没有获取验证码 直接向前端报错
            if (imageCodeValue == null){ // 验证码错误或者是验证码过期
                throw new BusinessException("请重新输入验证码");
            }
            // 3.1.2 获取验证码后判断验证码与redis中是否一致
            if(!imageCodeValue.toString().equalsIgnoreCase(imageCode)){
                throw new BusinessException("验证错误！");
            }
            // 4、校验验证码是否已经发送
            // 4.1根据手机号拼接业务键：从redis获取短信验证码  key：register：1442342232
            String businessKey = BaseConstants.VerifyConstants.BUSINESS_REGISTER_PREFIX + phone;
            sendSmsCode(businessKey);
//            // 根据key获取redis中的验证码smsCode
//            Object smsCode = redisTemplate.opsForValue().get(key);
//            String imgCode ="";
//            if (smsCode!=null){
//                // 4.1.2获取到了：判断是否过了重发时间1分钟  value  9527:23456789
//                String oldTime = smsCode.toString().split(":")[1]; // 获取时间
//                // 将String转换为Long类型
//                Long timeStr = Long.valueOf(oldTime);
//                //      小于1分钟：报错请勿重复获取验证码
//                if (System.currentTimeMillis()-timeStr <= 60*60*1000){
//                    throw new BusinessException("吃饱了，撑的？？");
//                }
//                //      大于1分钟：使用原来验证码。重新发送
//                imgCode = smsCode.toString().split(":")[0];
//            }else {
//                // 4.1.1获取不到  （说明已经过期直接生成新的验证码发送）
//                // 5、生成验证码
//                imgCode = StrUtils.getComplexRandomString(4);
//            }
//            // 将验证码拼接上时间戳
//            String imgCodeVaule = imgCode + ":" + System.currentTimeMillis();
//            // 6、保存到redis中
//            redisTemplate.opsForValue().set(key,imgCodeVaule,3,TimeUnit.MINUTES);
//            // 7、发送验证码
//            System.out.println(imgCode);
            return null;

        }
        return null;
    }

    /**
     * 公共代码
     * @param businessKey
     */
    private void sendSmsCode(String businessKey){
        // 4、校验验证码是否已经发送
        // 4.1根据手机号拼接业务键：从redis获取短信验证码  key：register：1442342232
        // 根据key获取redis中的验证码smsCode
        Object smsCode = redisTemplate.opsForValue().get(businessKey);
        String imgCode ="";
        if (smsCode!=null){
            // 4.1.2获取到了：判断是否过了重发时间1分钟  value  9527:23456789
            String oldTime = smsCode.toString().split(":")[1]; // 获取时间
            // 将String转换为Long类型
            Long timeStr = Long.valueOf(oldTime);
            //      小于1分钟：报错请勿重复获取验证码
            if (System.currentTimeMillis()-timeStr <= 60*60*1000){
                throw new BusinessException("吃饱了，撑的？？");
            }
            //      大于1分钟：使用原来验证码。重新发送
            imgCode = smsCode.toString().split(":")[0];
        }else {
            // 4.1.1获取不到  （说明已经过期直接生成新的验证码发送）
            // 5、生成验证码
            imgCode = StrUtils.getComplexRandomString(4);
        }
        // 将验证码拼接上时间戳
        String imgCodeVaule = imgCode + ":" + System.currentTimeMillis();
        // 6、保存到redis中
        redisTemplate.opsForValue().set(businessKey,imgCodeVaule,3,TimeUnit.MINUTES);
        // 7、发送验证码
        System.out.println(imgCode);
    }
}